package com.dangs.downloader;


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import android.os.Environment;
import android.text.TextUtils;

import com.dangs.downloader.download.Downloader;

public class HttpHelper {

    private static final String TAG = "HttpHelper";
    static private HttpHelper instance;
    private DownloadInterface listener;
    private static final int CORE_POOL_SIZE = 1;
    private static final int MAX_IMUM_POOL_SIZE = 255;
    private String port = "";

    private static Runtime mRun = Runtime.getRuntime();// 获取当前运行环境，来执行ping，相当于windows的cmd
    private static ThreadPoolExecutor mExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_IMUM_POOL_SIZE,
            2000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(
            CORE_POOL_SIZE));


    public static HttpHelper getInstance(DownloadInterface listener) {
        if (instance == null) {
            synchronized (HttpHelper.class) {
                instance = new HttpHelper();
            }
        }
        if (listener != null) {
            instance.listener = listener;
        }
        return instance;
    }

    public void download(String url, int thread) {
        mExecutor.execute(() -> {
            L.d(TAG, "download:" + url);
            if (TextUtils.isEmpty(url)) {
                return;
            }
            Downloader downloader = new Downloader(url, thread);
            downloader.setListener(listener);
            downloader.start();
        });
    }

    public static List<String> getHttpText(String web, String subString) {
        List<String> list = new ArrayList<>();
        L.d(TAG, "get text form:" + web + ", match:" + subString);
        try {
            if (TextUtils.isEmpty(web)) {
                return list;
            }
            URL url = new URL(web);
            URLConnection connection = url.openConnection();
            connection.setReadTimeout(200);
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
            BufferedWriter writer = new BufferedWriter(new FileWriter(downloadDir + "/data.html"));
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.contains(subString)) {
                    int startIndex = line.indexOf("value=\"") + 7;
                    int endIndex = -1;
                    if (startIndex > 0 && startIndex < line.length()) {
                        endIndex = line.indexOf("\"", startIndex);
                    }
                    if (endIndex > 0 && endIndex > startIndex) {
                        list.add(line.substring(startIndex, endIndex));
                    }
                }
                writer.write(line);
                writer.newLine();
            }
            reader.close();
            writer.close();
        } catch (Exception e) {
            L.e(TAG, "get text from " + web + ", err:" + e.toString());
        }
        return list;
    }


    public static List<String> scan() {
        List<String> validIp = new ArrayList<>();
        String hostIP = getHostIP();
        String preIP = null;
        if (!TextUtils.isEmpty(hostIP)) {
            if (hostIP.contains(".")) {
                int index = hostIP.lastIndexOf(".") + 1;
                if (index <= hostIP.length()) {
                    preIP = hostIP.substring(0, index);
                }
            }
        }
        if (TextUtils.isEmpty(preIP)) {
            L.e(TAG, "扫描失败，请检查wifi网络");
            return null;
        }
        for (int i = 1; i < 255; i++) {// 创建256个线程分别去ping
            final int lastAddress = i;// 存放ip最后一位地址 1-255
            String finalPreIP = preIP;
            Runnable run = () -> {
                String currnetIp = finalPreIP + lastAddress;
                String ping = "ping -c 1 -w 3 " + currnetIp;
                if (currnetIp.equals(hostIP)) // 如果与本机IP地址相同,跳过
                    return;
                try {
                    Process mProcess = mRun.exec(ping);
                    int result = mProcess.waitFor();
                    L.d(TAG, "正在扫描的IP地址为：" + currnetIp + "返回值为：" + result);
                    if (result == 0) {
                        L.d(TAG, "扫描成功,Ip地址为：" + currnetIp);
                        validIp.add(currnetIp);
                    } else {
                        // 扫描失败
                        L.d(TAG, "扫描失败");
                    }
                    if (mProcess != null) {
                        mProcess.destroy();
                    }
                } catch (Exception e) {
                    L.e(TAG, "扫描异常" + e.toString());
                }
            };
            mExecutor.execute(run);
        }
        mExecutor.shutdown();
        while (true) {
            try {
                if (mExecutor.isTerminated()) {// 扫描结束,开始验证
                    L.d(TAG, "扫描结束,总共成功扫描到" + validIp.size() + "个设备.");
                    break;
                }
            } catch (Exception e) {
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return validIp;
    }


    public static String getHostIP() {
        String hostIp = null;
        try {
            Enumeration nis = NetworkInterface.getNetworkInterfaces();
            InetAddress ia = null;
            while (nis.hasMoreElements()) {
                NetworkInterface ni = (NetworkInterface) nis.nextElement();
                Enumeration<InetAddress> ias = ni.getInetAddresses();
                while (ias.hasMoreElements()) {
                    ia = ias.nextElement();
                    if (ia instanceof Inet6Address) {
                        continue;// skip ipv6
                    }
                    String ip = ia.getHostAddress();
                    if (!"127.0.0.1".equals(ip)) {
                        hostIp = ia.getHostAddress();
                        break;
                    }
                }
            }
        } catch (SocketException e) {
            L.i(TAG, "SocketException");
            e.printStackTrace();
        }
        return hostIp;

    }


    public static String getLocAddrIndex() {
        String hostIP = getHostIP();
        L.d(TAG, "host ip:" + hostIP);
        if (!TextUtils.isEmpty(hostIP)) {
            if (hostIP.contains(".")) {
                int index = hostIP.lastIndexOf(".") + 1;
                if (index <= hostIP.length()) {
                    return hostIP.substring(0, index);
                }
            }
        }
        return null;
    }

    public interface DownloadInterface {
        public void onStartDownload(long startTime);

        public void onGetFileSize(long fileSize);

        public void onDownloading(long progress, float speed);

        public void onDownloadComplete(long totalTime);
        public void onDownloadErr(Exception e);
    }
}